package com.v1.admin.manage;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentException;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.v1.model.BaseElement;
import com.v1.model.CategoryWapper;
import com.v1.model.ItemWapper;
import com.v1.model.Tag;

@Service("flickr")
public class FlickrFeed extends BaseFeed {

	public FlickrFeed() throws ParserConfigurationException {
		super();
	}

	public CategoryWapper parse(String url) throws Exception {
		Document document = builder.parse(new URL(url).openStream());
		Node root = (Node) xpath.evaluate("/feed", document, XPathConstants.NODE);
		CategoryWapper category = parseCategory(root);
		NodeList entrys = (NodeList) xpath.evaluate("./entry", root, XPathConstants.NODESET);
		List<ItemWapper> items = parseItems(entrys);
		category.setItems(items);
		return category;
	}

	private List<ItemWapper> parseItems(NodeList entrys) {
		int length = entrys.getLength();
		List<ItemWapper> items = new ArrayList<ItemWapper>();
		for (int i = 0; i < length; i++) {
			Node entry = entrys.item(i);
			ItemWapper item = parseItem(entry);
			items.add(item);
		}
		return items;
	}

	private ItemWapper parseItem(Node entry) {
		NodeList childNodes = entry.getChildNodes();
		int length = childNodes.getLength();
		ItemWapper item = new ItemWapper();
		List<Tag> tags = new ArrayList<Tag>();
		item.setTags(tags);
		for (int i = 0; i < length; i++) {
			Node node = childNodes.item(i);
			String nodeName = node.getNodeName();
			if ("title".equals(nodeName)) {
				String nodeValue = node.getTextContent();
				item.setName(nodeValue);
			} else if ("content".equals(nodeName)) {
				String nodeValue = node.getTextContent();
				int index = nodeValue.indexOf("<img src=\"") + "<img src=\"".length();
				int end = nodeValue.indexOf("\"", index);
				item.setThumb(nodeValue.substring(index, end));
				int matches = StringUtils.countMatches(nodeValue, "<p>");
				if (matches > 2) {
					int index2 = nodeValue.lastIndexOf("<p>") + "<p>".length();
					item.setDigest(nodeValue.substring(index2, nodeValue.length() - 4));
				}

			} else if ("link".equals(nodeName)) {
				parseLink(item, node);
				NamedNodeMap attributes = node.getAttributes();
				Node namedItem = attributes.getNamedItem("type");
				if (namedItem != null && "image/jpeg".equals(namedItem.getNodeValue())) {
					item.setUrl(attributes.getNamedItem("href").getNodeValue());
				}
			} else if ("category".equals(nodeName)) {
				NamedNodeMap attributes = node.getAttributes();
				Node namedItem = attributes.getNamedItem("term");
				String nodeValue = namedItem.getNodeValue();
				if (StringUtils.isNotEmpty(nodeValue)) {
					Tag tag = new Tag();
					tag.setTag(nodeValue);
					tags.add(tag);
				}
			}
		}
		return item;
	}

	private CategoryWapper parseCategory(Node node) {
		NodeList childNodes = node.getChildNodes();
		int length = childNodes.getLength();
		CategoryWapper category = new CategoryWapper();
		for (int i = 0; i < length; i++) {
			Node item = childNodes.item(i);
			String nodeName = item.getNodeName();
			if ("link".equals(nodeName)) {
				parseLink(category, item);
			} else if ("icon".equals(nodeName)) {
				String nodeValue = item.getTextContent();
				category.setThumb(nodeValue.substring(0, nodeValue.length() - 5) + "m"
						+ nodeValue.substring(nodeValue.length() - 4));
			} else if ("subtitle".equals(nodeName)) {
				String nodeValue = item.getTextContent();
				category.setDigest(nodeValue);
			} else if ("title".equals(nodeName)) {
				String nodeValue = item.getTextContent();
				category.setName(nodeValue);
			}
		}
		return category;
	}

	private void parseLink(BaseElement model, Node node) {
		NamedNodeMap attributes = node.getAttributes();
		Node namedItem = attributes.getNamedItem("type");
		if (namedItem != null && "text/html".equals(namedItem.getNodeValue())) {
			model.setLink(attributes.getNamedItem("href").getNodeValue());
		}
	}

	/**
	 * @param args
	 * @throws DocumentException
	 * @throws URISyntaxException
	 * @throws MalformedURLException
	 */
	public static void main(String[] args) throws Exception {
		// SAXReader reader = new SAXReader();
		String fileName = "http://api.flickr.com/services/feeds/photoset.gne?set=72157629463029594&nsid=77372048@N04&lang=zh-hk";
		new FlickrFeed().parse(fileName);

		URL url = new URL(fileName);
		// Document document = reader.read(url);
		// Element link = (Element) ((Element) document.getRootElement()
		// .elements().get(8)).elements().get(9);
		// // link.getUniquePath()Path();
		// List selectNodes = document.selectNodes("/feed/entry/link[@href]");
		// System.out.println(link);

		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document document = builder.parse(url.openStream());
		XPath xpath = XPathFactory.newInstance().newXPath();
		NodeList nodelist = (NodeList) xpath.evaluate("/feed/entry/link[@type=\"image/jpeg\"]", document,
				XPathConstants.NODESET);
		int length = nodelist.getLength();
		for (int i = 0; i < length; i++) {
			Node item = nodelist.item(i);
			NamedNodeMap attributes = item.getAttributes();
			Node namedItem = attributes.getNamedItem("href");
			Object nodeValue = namedItem.getNodeValue();
			System.out.println(nodeValue);
		}
		// System.out.println(nodelist);
	}

}
